package exredis

import "github.com/gomodule/redigo/redis"

// HDEL key field [field ...]
// 删除哈希表 key 中的一个或多个指定域，不存在的域将被忽略。
func (r *Redis) HDEL(key, field string, fields ...string) (int, error) {
	return redis.Int(r.PreDo("HDEL", KeyFieldToInterface(key, field, fields...)...))
}

// HEXISTS key field
// 查看哈希表 key 中，给定域 field 是否存在。
func (r *Redis) HEXISTS(key string) (bool, error) {
	return redis.Bool(r.PreDo("HEXISTS", key))
}

// HGET key field
// 返回哈希表 key 中给定域 field 的值。
func (r *Redis) HGET(key string) (string, error) {
	return redis.String(r.PreDo("HGET", key))
}

// HGETALL key
// 返回哈希表 key 中，所有的域和值。
// 在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
func (r *Redis) HGETALL(key string) (map[string]string, error) {
	return redis.StringMap(r.PreDo("HGETALL", key))
}

// HINCRBY key field increment
// 为哈希表 key 中的域 field 的值加上增量 increment 。
// 增量也可以为负数，相当于对给定域进行减法操作。
// 如果 key 不存在，一个新的哈希表被创建并执行 HINCRBY 命令。
// 如果域 field 不存在，那么在执行命令前，域的值被初始化为 0 。
// 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
// 本操作的值被限制在 64 位(bit)有符号数字表示之内。
func (r *Redis) HINCRBY(key, field string, decrement int64) (string, error) {
	return redis.String(r.PreDo("HINCRBY", key, field, decrement))
}

// HINCRBYFLOAT key field increment
// 为哈希表 key 中的域 field 加上浮点数增量 increment 。
// 如果哈希表中没有域 field ，那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ，然后再执行加法操作。
// 如果键 key 不存在，那么 HINCRBYFLOAT 会先创建一个哈希表，再创建域 field ，最后再执行加法操作。
// 当以下任意一个条件发生时，返回一个错误：
// 域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存，所以它们都属于字符串类型）
// 域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)
// HINCRBYFLOAT 命令的详细功能和 INCRBYFLOAT 命令类似，请查看 INCRBYFLOAT 命令获取更多相关信息。
func (r *Redis) HINCRBYFLOAT(key string, decrement float32) (string, error) {
	return redis.String(r.PreDo("HINCRBYFLOAT", key, decrement))
}

// HKEYS key
// 返回哈希表 key 中的所有域。
func (r *Redis) HKEYS(key string) ([]string, error) {
	return redis.Strings(r.PreDo("HKEYS", key))
}

// HLEN key
// 返回哈希表 key 中域的数量。
func (r *Redis) HLEN(key string) (int64, error) {
	return redis.Int64(r.PreDo("HLEN", key))
}

// HMGET key field [field ...]
// 返回哈希表 key 中，一个或多个给定域的值。
// 如果给定的域不存在于哈希表，那么返回一个 nil 值。
// 因为不存在的 key 被当作一个空哈希表来处理，所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。
func (r *Redis) HMGET(key, field string, fields ...string) ([]string, error) {
	return redis.Strings(r.PreDo("HMGET", KeyFieldToInterface(key, field, fields...)...))
}

// HMSET key field value [field value ...]
// 同时将多个 field-value (域-值)对设置到哈希表 key 中。
// 此命令会覆盖哈希表中已存在的域。
// 如果 key 不存在，一个空哈希表被创建并执行 HMSET 操作。
func (r *Redis) HMSET(key, field, value string, fields ...string) (bool, error) {
	return IsOK(redis.String(r.PreDo("HMSET", KeyFieldValueToInterface(key, field, value, fields...)...)))
}

// HSET key field value
// 将哈希表 key 中的域 field 的值设为 value 。
// 如果 key 不存在，一个新的哈希表被创建并进行 HSET 操作。
// 如果域 field 已经存在于哈希表中，旧值将被覆盖。
func (r *Redis) HSET(key, field, value string) (bool, error) {
	return redis.Bool(r.PreDo("HSET", KeyFieldValueToInterface(key, field, value)...))
}

// HSETNX key field value
// 将哈希表 key 中的域 field 的值设置为 value ，当且仅当域 field 不存在。
// 若域 field 已经存在，该操作无效。
// 如果 key 不存在，一个新哈希表被创建并执行 HSETNX 命令。
func (r *Redis) HSETNX(key, field, value string) (bool, error) {
	return redis.Bool(r.PreDo("HSETNX", KeyFieldValueToInterface(key, field, value)...))
}

// HVALS key
// 返回哈希表 key 中所有域的值。
func (r *Redis) HVALS(key string) ([]string, error) {
	return redis.Strings(r.PreDo("HVALS", key))
}

//TODO:HSCAN key cursor [MATCH pattern] [COUNT count]
func (r *Redis) HSCAN() {
	//TODO:
}

// HSTRLEN key field
// 返回哈希表 key 中， 与给定域 field 相关联的值的字符串长度（string length）。
// 如果给定的键或者域不存在， 那么命令返回 0 。
func (r *Redis) HSTRLEN(key, field string) (int64, error) {
	return redis.Int64(r.PreDo("HSTRLEN", key, field))
}
